package com.hxd.otc.module.my.model;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.hxd.otc.api.Constant;
import com.hxd.otc.api.IUserApi;
import com.hxd.otc.base.BaseBean;
import com.hxd.otc.common.UserHelper;
import com.hxd.otc.common.enums.CountryCodeEnum;
import com.hxd.otc.module.login.bean.AccountBean;
import com.hxd.otc.module.login.bean.PhoneCodeBean;
import com.hxd.otc.module.my.bean.AppInfoBean;
import com.hxd.otc.module.my.bean.BaseListBean;
import com.hxd.otc.module.my.bean.GoogleCreateBean;
import com.hxd.otc.module.my.bean.ImageCodeBean;
import com.hxd.otc.module.my.bean.MerchantsOrderBean;
import com.hxd.otc.module.my.bean.NoticeBean;
import com.hxd.otc.module.my.bean.RealNameAuthRuleInfoBean;
import com.hxd.otc.module.my.bean.RegisterRequest;
import com.hxd.otc.module.my.bean.RongCloudTokenBean;
import com.hxd.otc.module.my.bean.RongUserInfoBean;
import com.hxd.otc.module.my.bean.UserStatusBean;
import com.hxd.otc.module.order.bean.FinacialBean;
import com.hxd.otc.module.order.bean.StableCurrencyBean;
import com.hxd.otc.net.BaseObserver;
import com.hxd.otc.net.HttpFileObserver;
import com.hxd.otc.net.RetrofitManager;
import com.hxd.otc.utils.EncryptUtils;
import com.hxd.otc.utils.FileUtils;
import com.uber.autodispose.AutoDisposeConverter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;

/**
 * Created by lzy on 2018/6/13 0013.
 * description ${用户接口model}
 */
public class UserModel {

    private UserModel() {
    }


    private static class SingletonHolder {
        private static final UserModel instance = new UserModel();
    }

    public static UserModel getInstance() {
        return UserModel.SingletonHolder.instance;
    }

    public void login(@NonNull String phoneNumber, @NonNull String encryptedPassword, String sessionID, BaseObserver observer,
                      AutoDisposeConverter<BaseBean<AccountBean>> converter) {

        HashMap<String, Object> map = new HashMap<>();
        map.put("username", phoneNumber);
        map.put("password", encryptedPassword);
        map.put("loginSource", "otc");
        if (!TextUtils.isEmpty(sessionID)) {
            map.put("source", "Android");
            map.put("scene", "register");
            map.put("appKey", Constant.Login.VERIFYTYPECODE);
            map.put("sessionId", sessionID);
        }
        RetrofitManager.getDefault().create(IUserApi.class)
                .login(map)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);

    }

    public void forgetPasswordOfPhone(String mobile, String password, String code, String countryId, @NonNull BaseObserver<String> observer,
                                      AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().forgetPasswordOfPhone(mobile, EncryptUtils.getRSA(password), code, countryId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter).subscribe(observer);
    }

    public void updatename(String name, BaseObserver observer, AutoDisposeConverter<BaseBean> converter) {
    }

    public void updatenick(String nickName, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().updateNickName(nickName)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    public void logout(BaseObserver observer, AutoDisposeConverter<BaseBean> converter) {
        getUserApi().logout()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    public void getUpdateAppInfo(BaseObserver<AppInfoBean> observer,
                                 AutoDisposeConverter<BaseBean<AppInfoBean>> converter) {
        getUserApi().getUpdateAppInfo("2")
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    public void getRongCloudToken(BaseObserver<RongCloudTokenBean> observer) {
        getUserApi().getRongCloudToken()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
    }

    public void businessOrderInfo(String createTime, int pageNo, int pageSize, BaseObserver<ArrayList<MerchantsOrderBean>> observer, AutoDisposeConverter<BaseBean<ArrayList<MerchantsOrderBean>>> converter) {
        getUserApi().businessOrderInfo(createTime, pageNo, pageSize)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    public void getUserInfoById(String id, BaseObserver<RongUserInfoBean> observer, AutoDisposeConverter<BaseBean<RongUserInfoBean>> converter) {
        Observable<BaseBean<RongUserInfoBean>> baseBeanObservable = getUserApi().getUserInfoById(id)
                .observeOn(AndroidSchedulers.mainThread());
        if (converter != null) {
            baseBeanObservable.as(converter).subscribe(observer);
        } else {
            baseBeanObservable.subscribe(observer);
        }
    }

    /**
     * 校验手机号是否被绑定过
     */
    public void findUser(String phone, BaseObserver<ImageCodeBean> observer, AutoDisposeConverter<BaseBean<ImageCodeBean>> converter) {
        getUserApi().findUser(phone)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 修改绑定手机号时发送手机验证码
     */
    public void getUpdatePhoneVerCode(String phone, String countryId, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().updateMobileSms(phone, countryId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 未绑定过手机号的用户，进行绑定手机号时调用发送验证码
     */
    public void sendMobileSms(String phone, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().sendMobileSms(phone)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }


    /**
     * 绑定手机
     */
    public void bindPhone(String phone, String verCode, String countryId, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().bindPhone(phone, verCode, countryId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 修改绑定手机
     */
    public void updatePhone(String newPhone, String oldCode, String newCode, String countryId,BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().updatePhone(newPhone, oldCode, newCode,countryId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 更新交易密码
     *
     * @param loginPassword
     * @param payPassword
     * @param verCode
     */
    public void updateExPassword(String loginPassword, String payPassword, String verCode, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().updateExPassword(loginPassword, verCode, payPassword)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 实名验证  国家,证件类型(1-身份证，2-护照),真实姓名，证件号码
     */
    public void realNameVerify(String idCard, String age, int sex, String realName, String address, CountryCodeEnum countryCodeEnum, String cardUpId,
                               String cardDownId, String cardFaceId, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().realNameVerify(idCard, age, sex, realName, address, countryCodeEnum.getValue(), cardUpId, cardDownId, cardFaceId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 实名验证  国家,证件类型(1-身份证，2-护照),真实姓名，证件号码
     */
    public void realNameVerifyOfV1(String idCard, String age, int sex, String realName, String address, CountryCodeEnum countryCodeEnum,
                                   BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().realNameVerifyOfV1(idCard, age, sex, realName, address, countryCodeEnum.getValue())
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * @param cardUpId   身份证正面
     * @param cardDownId 身份证反面
     * @param cardFaceId 手持身份证
     */
    public void realNameVerifyOfV2(String cardUpId, String cardDownId, String cardFaceId, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().realNameVerifyOfV2(cardUpId, cardDownId, cardFaceId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 获取实名认证状态
     */
    public void findCardStatus(BaseObserver<UserStatusBean> observer, AutoDisposeConverter<BaseBean<UserStatusBean>> converter) {
        getUserApi().findCardStatus()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 获取谷歌code
     */
    public void getGoogleCode(BaseObserver<GoogleCreateBean> observer, AutoDisposeConverter<BaseBean<GoogleCreateBean>> converter) {
        getUserApi().getGoogleCode()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 绑定谷歌验证码
     *
     * @param googleCode   谷歌验证码
     * @param googleSecret 谷歌密钥
     * @param phoneCode    手机验证码
     */
    public void bindGoogleCode(String googleCode, String googleSecret, String phoneCode, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().bindGoogleCode(googleCode, googleSecret, phoneCode)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 重置登录密码
     *
     * @param newpassword 新登录密码
     * @param oldPassword 旧登录密码
     */
    public void updateLoginPassword(String newpassword, String oldPassword, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().updateLoginPassword(EncryptUtils.getRSA(newpassword), EncryptUtils.getRSA(oldPassword))
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 注册或绑定邮箱时获取邮箱验证码
     *
     * @param mail      邮箱
     * @param type      [binder,register]
     * @param source    [Android]
     * @param scene     [register]
     * @param sessionId 阿里滑块sessionId
     */
    public void getEmailCode(BaseObserver<ImageCodeBean> observer, AutoDisposeConverter<BaseBean<ImageCodeBean>> converter,
                             String mail, String type, String source, String scene, String sessionId) {
        getUserApi().getEmailCode(mail, type, source, scene, Constant.Login.VERIFYTYPECODE, sessionId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 绑定邮箱
     *
     * @param email
     * @param verCode
     */
    public void bindEmail(String email, String verCode, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().bindEmail(email, verCode)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 用于修改验证方式，验证"验证方式--手机验证"时发送短信验证码
     *
     * @param smsType ex_mobile :发送用于交易时验证的短信验证码;
     *                exchange_pass：用于修改验证方式;
     *                ex_password：交易密码;
     *                bander_google：谷歌认证;
     */
    public void sendExValidTypeMobileSms(String smsType, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().sendExValidTypeMobileSms(smsType)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 用于修改、验证"验证方式--邮箱验证"时发送短信验证码
     *
     * @param smsType ex_mail :发送用于交易时验证的短信验证码;
     *                exchange_pass：用于修改验证方式;
     */
    public void sendExValidTypeEmail(String smsType, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().sendExValidTypeEmail(smsType)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 设置验证方式
     *
     * @param exValidType
     */
    public void setValidType(String exValidType, BaseObserver<ImageCodeBean> observer, AutoDisposeConverter<BaseBean<ImageCodeBean>> converter) {
        getUserApi().setValidType(exValidType)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 修改验证方式
     *
     * @param exValidType 新设置的交易验证方式
     * @param code        当前验证方式的验证码或交易密码
     */
    public void changeExValidType(String exValidType, String code, BaseObserver<ImageCodeBean> observer, AutoDisposeConverter<BaseBean<ImageCodeBean>> converter) {
        getUserApi().changeExValidType(exValidType, code)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 用于交易时，验证方式的验证
     *
     * @param code 当前验证方式的验证码
     */
    public void validPayVerCode(String code, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().validPayVerCode(code)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }


    public void getNoticeList(int currentPage, int showCount, BaseObserver observer, AutoDisposeConverter<BaseBean<BaseListBean<NoticeBean>>> converter) {
        getUserApi().getNoticeList(currentPage, showCount, UserHelper.getId())
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 标记消息已读
     *
     * @param noticeId
     * @param observer
     * @param converter
     */
    public void lookList(String noticeId, BaseObserver observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().lookList(noticeId, UserHelper.getId())
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    /**
     * 注册时发送手机验证码
     *
     * @param mobile    手机号
     * @param type      [register(注册),reset（忘记密码）]
     * @param source    [Android ...]
     * @param scene     [register]
     * @param sessionId 阿里滑块sessionId
     */
    public void sendPhoneCodeWithVerif(BaseObserver<ImageCodeBean> observer, AutoDisposeConverter<BaseBean<ImageCodeBean>> converter,
                                       String mobile, String type, String source, String scene, String sessionId, String countryId) {
        getUserApi()
                .getPhoneCodeWithVerif(mobile, type, source, scene, Constant.Login.VERIFYTYPECODE, sessionId, countryId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);

    }

    public void register(BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter,
                         RegisterRequest request) {

        getUserApi()
                .register(request.registerType, request.mail, request.mobile,
                        EncryptUtils.getRSA(request.password), request.code, request.inviteCode, request.countryId)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);

    }

    /**
     * 获取等级限制规则
     */
    public void getRealNameAuthRuleInfo(BaseObserver<ArrayList<RealNameAuthRuleInfoBean>> observer,
                                        AutoDisposeConverter<BaseBean<ArrayList<RealNameAuthRuleInfoBean>>> converter) {
        getUserApi()
                .getRealNameAuthRuleInfo()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    public void getStableCurrencyList(BaseObserver observer, AutoDisposeConverter<BaseBean<StableCurrencyBean>> converter, @NonNull int... category) {

        getUserApi()
                .getStableCurrencyList()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);

    }

    public void getFinancialList(BaseObserver observer, AutoDisposeConverter<BaseBean<FinacialBean>> converter, int pageSize, int currPage) {

        getUserApi()
                .getFinancialList(pageSize, currPage)
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);

    }

    public void downLoadFile(final String downloadUrl, final String fileName, final HttpFileObserver observer,
                             final AutoDisposeConverter<ResponseBody> converter) {

        getUserApi()
                .downloadFile(downloadUrl)
                .subscribeOn(Schedulers.io())//指定耗时进程
                .observeOn(Schedulers.newThread())//指定doOnNext执行线程是新线程
                .doOnNext(new Consumer<ResponseBody>() {
                    @Override
                    public void accept(ResponseBody responseBody) throws Exception {
                        //下载文件，保存到本地
                        boolean isSuccess = FileUtils.downloadAndSave(responseBody, fileName);
                        observer.setFileSaveSuccess(isSuccess);
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//指定最后观察者在主线程
                .as(converter)
                .subscribe(observer);
    }

    public void easemobRegister(String csUsername, String csPass, BaseObserver<String> observer, AutoDisposeConverter<BaseBean<String>> converter) {
        getUserApi().easemobRegister()
                .observeOn(AndroidSchedulers.mainThread())
//                .as(converter)
                .subscribe(observer);
    }

    public void getNosenseMessageNotice(BaseObserver<Integer> observer, AutoDisposeConverter<BaseBean<Integer>> converter) {
        getUserApi().getNosenseMessageNotice()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }

    public void getZoneBean(BaseObserver<List<PhoneCodeBean>> observer, AutoDisposeConverter<BaseBean<List<PhoneCodeBean>>> converter) {
        getUserApi().getPhoneCodeBean()
                .observeOn(AndroidSchedulers.mainThread())
                .as(converter)
                .subscribe(observer);
    }


    private IUserApi getUserApi() {
        return RetrofitManager.getDefault().create(IUserApi.class);
    }

}
